﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using WebGioiThieu.Models;

namespace WebGioiThieu.Areas.Admin.Controllers
{
    [CustomAuthorize]
    public class RoleController : Controller
    {
        private IntroductionWebDBEntities db = new IntroductionWebDBEntities();

        //
        // GET: /Admin/Role/
        [CustomAuthorize]
        public ActionResult Index(string key)
        {
            try
            {
                IEnumerable<aspnet_Roles> roles;
                if (!string.IsNullOrEmpty(key))
                {
                    string keysearch = key.ToLower();
                    roles = (from r in db.aspnet_Roles where (r.RoleName.Contains(keysearch) || r.Description.Contains(keysearch)) select r).ToList();
                }
                else
                {
                    roles = db.aspnet_Roles.ToList();

                }
                return View(roles);
            }
            catch
            {
                return Error();
            }
        }

        private PartialViewResult Error()
        {
            return PartialView("Error", Url.Action("Index"));
        }
        //
        // GET: /Admin/Role/Details/5
        [CustomAuthorize]
        public ActionResult Details(string id)
        {
            try
            {
                var role = db.aspnet_Roles.SingleOrDefault(m => m.RoleId.CompareTo(new Guid(id)) == 0);
                if (role == null)
                {
                    throw new Exception("khong ton tai!");
                }
                return View(role);
            }
            catch
            {
                return Error();
            }
        }

        //
        // GET: /Admin/Role/Create
        [CustomAuthorize]
        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Admin/Role/Create
        [CustomAuthorize]
        [HttpPost]
        public ActionResult Create(aspnet_Roles role)
        {
            if (ModelState.IsValid)
            {
                System.Web.Security.Roles.CreateRole(role.RoleName);
                return RedirectToAction("Index");
            }
            return View(role);
        }

        //
        // GET: /Admin/Role/Edit/5
       
        public ActionResult Edit(string id)
        {
            try
            {
                var role = db.aspnet_Roles.FirstOrDefault(m => m.RoleId.CompareTo(new Guid(id)) == 0);
                if (role == null)
                {
                    throw new Exception("khong ton tai");
                }
                List<Type> controllerTypes = MvcHelper.GetControllerTypes();

                var groupPermissions = new List<KeyValuePair<KeyValuePair<string, string>, List<string>>>();

                foreach (var type in controllerTypes)
                {
                    string areaName = "";
                    if (type.FullName.Contains(".Areas."))
                    {
                        string[] parts = type.FullName.Split('.');
                        areaName = parts[parts.ToList().IndexOf("Areas") + 1];
                    }
                    List<string> actionNames = MvcHelper.GetActionNames(type);
                    groupPermissions.Add(new KeyValuePair<KeyValuePair<string, string>, List<string>>(new KeyValuePair<string, string>(type.Name.Replace("Controller", ""), areaName), actionNames));
                }
                ViewBag.RuleAssist = role.AccessRules.ToList();
                groupPermissions.Sort((m, n) => m.Key.Value.CompareTo(n.Key.Value));
                ViewBag.GroupPermission = groupPermissions;
                return View(role);
            }
            catch
            {
                return Error();
            }
        }

        //
        // POST: /Admin/Role/Edit/5
        [CustomAuthorize]
        [HttpPost]
        public ActionResult Edit(string id, aspnet_Roles model, FormCollection collection)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    model.RoleId = new Guid(id);
                    model.LoweredRoleName = model.RoleName.ToLower();

                    db.Entry(model).State = EntityState.Modified;
                    
                    db.SaveChanges();
                    var acess_rules = db.AccessRules.Where(rl=> rl.RoleId == model.RoleId);

                    foreach (string name in collection.AllKeys)
                    {
                        if (name.StartsWith("[Controller]"))
                        {
                            string name_new = name.Replace("[Controller]", "");
                            AccessRule obj = new AccessRule() { AccessName = name_new, RoleId = new Guid(id), Activated = true };
                            var acess_rule = acess_rules.SingleOrDefault(rl => rl.AccessName == obj.AccessName);
                            if (acess_rule == null)
                            {
                                db.AccessRules.Add(obj);
                                db.SaveChanges();
                            }
                        }
                    }

                    var objects_del = (from AccessRule rl in acess_rules where !collection.AllKeys.Contains("[Controller]" + rl.AccessName) select rl).ToList();
                    objects_del.ForEach(rl => db.AccessRules.Remove(rl));
                    db.SaveChanges();
                    CustomAuthorizeAttribute.SetSessionAccess(HttpContext);
                    return RedirectToAction("Index");
                }

                var roleAccessRules = new List<AccessRule>();
                collection.AllKeys.ToList().ForEach(m =>
                {
                    if (m.Contains("[Controller]"))
                    {
                        roleAccessRules.Add(new AccessRule() { AccessName = m.Replace("[Controller]", ""), });
                    }
                });

                List<Type> controllerTypes = MvcHelper.GetControllerTypes();

                var groupPermissions = new List<KeyValuePair<KeyValuePair<string, string>, List<string>>>();

                foreach (var type in controllerTypes)
                {
                    string areaName = "";
                    if (type.FullName.Contains(".Areas."))
                    {
                        string[] parts = type.FullName.Split('.');
                        areaName = parts[parts.ToList().IndexOf("Areas") + 1];
                    }
                    List<string> actionNames = MvcHelper.GetActionNames(type);
                    groupPermissions.Add(new KeyValuePair<KeyValuePair<string, string>, List<string>>(new KeyValuePair<string, string>(type.Name.Replace("Controller", ""), areaName), actionNames));
                }
                ViewBag.RuleAssist = roleAccessRules;
                groupPermissions.Sort((m, n) => m.Key.Value.CompareTo(n.Key.Value));
                ViewBag.GroupPermission = groupPermissions;

                return View(model);
            }
            catch
            {
                return Error();
            }
        }

        [CustomAuthorize]
        public ActionResult Delete(string id)
        {
            try
            {
                var role = db.aspnet_Roles.SingleOrDefault(m => m.RoleId == new Guid(id));
                if (role == null)
                {
                    throw new Exception("khong ton tai!");
                }
                return View(role);
            }
            catch
            {
                return Error();
            }
        }

        //
        // POST: /Admin/Role/Delete/5
        [CustomAuthorize]
        [HttpPost]
        public ActionResult Delete(string id, FormCollection collection)
        {
            try
            {
                // TODO: Add delete logic here
                if (ModelState.IsValid)
                {
                    var role = db.aspnet_Roles.SingleOrDefault(m => m.RoleId.CompareTo(new Guid(id)) == 0);
                    if (role == null)
                    {
                        throw new Exception("khong ton tai!");
                    }
                    role.AccessRules.Clear();
                    db.SaveChanges();
                    var usesInRole = Roles.GetUsersInRole(role.RoleName);
                    if (usesInRole != null && usesInRole.Length > 0)
                    {
                        Roles.RemoveUsersFromRole(usesInRole, role.RoleName);
                    }
                    Roles.DeleteRole(role.RoleName, true);
                    return RedirectToAction("Index");
                }
                return Error();
            }
            catch
            {
                return Error();
            }
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}